import 'package:manager/configs/app_data.dart';
import 'package:common_ui/components/common_layout.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' hide MultipartFile, FormData;
import 'package:manager/configs/widget_ids.dart';
import 'package:manager/exts/app_ext.dart';
import 'package:manager/exts/storage_ext.dart';
import 'package:manager/http/app_exceptions.dart';
import 'package:manager/http/dio_manager.dart';
import 'package:manager/http/entity/base_response.dart';
import 'package:manager/services/preference_service.dart';

class BaseController extends GetxController {
  ///为了方便统一管理,这里将状态从state中拿出来放到controller中
  EmotionStatus status = EmotionStatus.FINISH;

  ///记录使用的方法
  ///1 为getData 2 为getAllData 3为getListData
  int requestType = 1;

  ///是否可以加载更多
  bool hasMore = false;
  int pageIndex = 1;
  int pageSize = 20;

  ///放置本页面添加的监听器
  final _listenerSet = <ValueSetter>{};

  dynamic get args {
    return Get.arguments;
  }

  ///结束当前页面
  void onBack() {
    showLog('onBack---${toString()}');
    Get.back();
  }

  ///结束页面[times]结束次数
  void close(int times) {
    Get.close(times);
  }

  ///返回到指定页面
  void popTo(String page) {
    Get.until(ModalRoute.withName(page));
  }

  ///直接移除页面路由
  void removeRoute(String page) {}

  ///结束当前页面
  void onBackResult<T>(T? result) {
    Get.back(result: result);
  }

  T findLogic<T>({String? tag}) {
    return Get.find<T>(tag: tag);
  }

  bool isRegister<T>({String? tag}) {
    return Get.isRegistered<T>(tag: tag);
  }

  ///加载中
  void loading() {
    status = EmotionStatus.LOADING;
    update([EMOTION_STATUS]);
  }

  void loadFinish() {
    status = EmotionStatus.FINISH;
    update([EMOTION_STATUS]);
  }

  void loadEmpty() {
    status = EmotionStatus.EMPTY;
    update([EMOTION_STATUS]);
  }

  void loadError() {
    status = EmotionStatus.ERROR;
    update([EMOTION_STATUS]);
  }

  Future<void> loadData() async {}

  ///加载正常数据
  Future<void> getCommonData<T>(
      String path, Map<String, dynamic> params, Function(T) success,
      {bool? show, Function(AppException)? error, bool? auto}) async {
    params['userId']=AppData.userId;
    requestType = 1;
    await DioManager().request<T>(path, params: params, onSuccess: (data) {
      success(data);
      if (auto ?? true) {
        loadFinish();
      }
    }, onError: (err) {
      error?.call(err);
      if (auto ?? true) {
        loadError();
      }
    }, show: show ?? false);
  }

  ///加载data字段中没有数据的类型
  ///[auto] 是否自动更新页面加载状态,默认true
  Future<void> getAllData<T extends BaseResponse>(
      String path, Map<String, dynamic> params, Function(T) success,
      {bool? show,
      Function(AppException)? error,
      bool? auto,
      String? notify,
      bool? toast}) async {
    params['userId']=AppData.userId;
    requestType = 2;
    await DioManager().requestAll<T>(path, params: params, onSuccess: (data) {
      success(data);
      if (auto ?? true) {
        loadFinish();
      }
    }, onError: (err) {
      if (toast ?? true) {
        showToast(err.msg);
      }
      error?.call(err);
      if (auto ?? true) {
        loadError();
      }
    }, show: show ?? false, notify: notify);
  }

  ///加载List 类型数据
  Future<void> getListData<T>(
      String path, Map<String, dynamic> params, Function(List<T>) success,
      {bool? show, Function(AppException)? error, bool? auto}) async {
    requestType = 3;
    params['userId']=AppData.userId;
    await DioManager().requestList<T>(path, params: params, onSuccess: (data) {
      hasMore = data.length >= pageSize;
      success(data);
      if (auto ?? true) {
        loadFinish();
      }
    }, onError: (err) {
      error?.call(err);
      if (auto ?? true) {
        loadError();
      }
    }, show: show ?? false);
  }

  ///加载List 类型数据
  Future<void> getPageData<T>(
      String path, Map<String, dynamic> params, Function(List<T>) success,
      {bool? show, Function(AppException)? error, bool? auto}) async {
    requestType = 4;
    params['userId']=AppData.userId;
    await DioManager().requestPage<T>(path, params: params, onSuccess: (data) {
      hasMore = data.hasMore;
      success(data.records);
      if (auto ?? true) {
        loadFinish();
      }
    }, onError: (err) {
      error?.call(err);
      if (auto ?? true) {
        loadError();
      }
    }, show: show ?? false);
  }

  void uploadFile<T extends BaseResponse>(String path, FormData files,
      {Map<String, dynamic>? params, Function(T)? success}) async {
    await DioManager().uploadFile<T>(path, files,
        params: params, onSuccess: success, onError: (e) {
      showToast(e.msg);
    }, show: true);
  }

  void retry() async {
    loading();
    await refreshData();
  }

  ///刷新数据
  Future<void> refreshData() async {
    hideSoftKeyboard();
    pageIndex = 1;
    await loadData();
    return Future.value(true);
  }

  ///加载更多,如果没有更多,则不做处理
  void loadMoreData() {
    if (!hasMore) {
      return;
    }
    pageIndex++;
    loadData();
  }

  @override
  void onClose() {
    _cleanListeners();
    super.onClose();
  }

  ///添加监听器,同时将改监听器放到Set集合中
  void addKeyListener(String key, ValueSetter listener) {
    _listenerSet.add(listener);
    watchData(key, listener);
  }

  ///在页面结束的时候移除本页面添加的监听器,防止消息重复通知
  void _cleanListeners() {
    findLogic<PreferenceService>().removeListenerList(_listenerSet);
  }
}
